package my.jpcap;

import java.util.Map;

import jpcap.JpcapCaptor;
import jpcap.NetworkInterface;

/**
 * 1.使用jpcap抓取网络流量的主类, 2.这个类要根据网卡个数,启动线程分别抓取各个网卡上的流量入中 3.生成图表的对象从流量表中取出数据
 * 4.这个类设计为单实例,在第一次调用时启动抓数据线程; 5.目前没有设计停止抓取机制....
 * 
 * @author www.NetJava.cn
 */
public class Tcpdump {
	/**
	 * 单实例调用：其它对象调用这个类的方法时,必须通过这个方法 这样,保证了流量统计线程的启动,且只启动了一次
	 * */
	public synchronized static Tcpdump ins() {
		if (null == tcpdump) {
			tcpdump = new Tcpdump();
			tcpdump.init();
		}
		return tcpdump;

	}

	/** 生成报表的Servlet调用用于生成图表中数据 */
	public Map<String, Integer> getNameTrafficMap() {
		return nameTrafficMap;
	}

	/**
	 * 根据网卡个数，启动统计线程 注意：本地地址，即127.0.0.1上的不统计
	 */
	private void init() {
		try {
			// 获取本机上的网络接口对象
			final NetworkInterface[] devices = JpcapCaptor.getDeviceList();
			for (int i = 0; i < devices.length; i++) {
				NetworkInterface nc = devices[i];
				// 大与零则为有效网卡,不抓本机地址.
				if (nc.addresses.length > 0) {
					// 一个网卡可能有多个地址,只取第一个地址
					String addr = nc.addresses[0].address.toString();
					// 创建某个卡口上的抓取对象,
					JpcapCaptor jpcap = JpcapCaptor.openDevice(nc, 5000, true,
							20);
					jpcap.setFilter(
							"src host 192.168.70.12",
							true);
					jpcap.setFilter(
							"dst host 192.168.0.205",
							true);

					// 创建对应的抓取线程并启动
					LoopPacketThread lt = new LoopPacketThread(jpcap, addr);
					lt.start();
					System.out.println(addr + "上的采集线程己启动************");
				}
			}
		} catch (Exception ef) {
			ef.printStackTrace();
			System.out.println("start caputerThread error ! ! ! !" + ef);
		}
	}

	/** IP和抓到包的长度放入hash表中,用表中长度加入放入的长度 */
	void putNetValue(String name, int value) {
		if (nameTrafficMap.containsKey(name)) {
			value = nameTrafficMap.get(name) + value;
			nameTrafficMap.put(name, value);
		} else {
			nameTrafficMap.put(name, value);
		}
	}

	private Tcpdump() {
	}

	/** 存入某个地址名字和流量统计值 */
	private Map<String, Integer> nameTrafficMap = new java.util.HashMap();
	// 单实例
	private static Tcpdump tcpdump = null;

	public static void main(String args[]) {
		// 启动统计线程
		Tcpdump.ins();
		// 模拟数据提取线程
		new Thread(new Runnable() {
			public void run() {
				while (true) {
					try {
						Thread.sleep(3000);
					} catch (Exception ef) {
					}
					System.out.println("***********统计到的数据************");
					System.out.println(Tcpdump.ins().getNameTrafficMap());
				}
			}
		}).start();
	}

}
